package com.fishery.customization.util;

import com.fishery.customization.entity.OneLevelLabel;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.util.Assert;

import java.io.*;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

public class DataUtil {

	public static void fill(Update update, Object source) {
		if (source == null) {
			throw new NullPointerException("Source is null");
		}
		Class<?> sourceClass = source.getClass();
		Field[] fields = sourceClass.getDeclaredFields();
		for (Field field : fields) {
			try {
				field.setAccessible(true);
				Object o = field.get(source);
				if (o != null) {
					update.set(field.getName(), field.get(source));
				}
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 从target中去除source中有的二级标签
	 *
	 * @param source
	 * @param target
	 */
	public static void exceptSameLabels(Collection<OneLevelLabel> source, Collection<OneLevelLabel> target) {
		Assert.notNull(source, "Source must not be null");
		Assert.notNull(source, "target must not be null");
		// 去除一级标签中需要权限的二级标签
		Iterator<OneLevelLabel> it = target.iterator();
		while (it.hasNext()) {
			OneLevelLabel tLabel = it.next();
			source.forEach(sLabel -> {
				if (tLabel.getChildren().isEmpty()) {
					return;
				}
				if (tLabel.getName().equals(sLabel.getName())) {
					// 进行去除重复的二级标签
					if (tLabel.getChildren().removeAll(sLabel.getChildren())) ;
					// 需要检测一级标签是否有子标签，如果没有需要将该一级标签删除
					if (tLabel.getChildren().isEmpty()) {
						it.remove();
					}
				}
			});
		}
	}

	/**
	 * 获取redis的key
	 *
	 * @param types
	 * @return
	 */
	public static String getRedisKey(List<String> types) {
		StringBuffer typesStr = new StringBuffer();
		types.sort((s1, s2) -> s1.charAt(0) - s2.charAt(0));
		types.forEach(type -> typesStr.append(type));
		return types.toString();
	}

	public static Object copyObjectDeeply(Object o) {
		// 采用序列化拷贝，深拷贝一份拓展标签，用于基地其它角色进行慢拓展使用
		ObjectOutputStream oos = null;
		ObjectInputStream ois = null;
		ByteArrayOutputStream bos = null;
		ByteArrayInputStream bis = null;
		Object copyObject = null;
		try {
			// 构建一个字节数组输出流
			bos = new ByteArrayOutputStream();
			// 采用对象序列化流装饰字节数组输出流
			oos = new ObjectOutputStream(bos);
			// 构建一个字节数组输入流
			bis = new ByteArrayInputStream(bos.toByteArray());
			// 采用对象反序列化流装饰字节输入流
			ois = new ObjectInputStream(bis);
			// 进行序列化和反序列化对对象进行深度拷贝
			oos.writeObject(o);
			copyObject = ois.readObject();
		} catch (Exception e) {
			e.printStackTrace();
			if (oos != null) {
				try {
					oos.close();
				} catch (IOException ex) {
					ex.printStackTrace();
				}
			}
			if (ois != null) {
				try {
					ois.close();
				} catch (IOException ex) {
					ex.printStackTrace();
				}
			}
			if (bos != null) {
				try {
					bos.close();
				} catch (IOException ex) {
					ex.printStackTrace();
				}
			}
			if (bis != null) {
				try {
					bis.close();
				} catch (IOException ex) {
					ex.printStackTrace();
				}
			}
		}
		return copyObject;
	}

}
